package com.example.smartpark.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.example.smartpark.exception.BusinessException;
import com.example.smartpark.dto.FeeStandardDTO;
import com.example.smartpark.dto.FeeStandardQueryDTO;
import com.example.smartpark.mapper.FeeStandardMapper;
import com.example.smartpark.model.FeeStandard;
import com.example.smartpark.service.FeeStandardService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;

import java.util.Date;
import java.util.stream.Collectors;

/**
 * 收费标准服务实现
 */
@Slf4j
@Service
public class FeeStandardServiceImpl extends ServiceImpl<FeeStandardMapper, FeeStandard> implements FeeStandardService {

    @Override
    public IPage<FeeStandardDTO> getFeeStandardPage(FeeStandardQueryDTO queryDTO) {
        log.info("分页查询收费标准列表: {}", queryDTO);
        
        // 构建查询条件
        LambdaQueryWrapper<FeeStandard> queryWrapper = new LambdaQueryWrapper<>();
        
        // 添加查询条件
        if (StringUtils.hasText(queryDTO.getName())) {
            queryWrapper.like(FeeStandard::getName, queryDTO.getName());
        }
        
        if (queryDTO.getSpaceType() != null) {
            queryWrapper.eq(FeeStandard::getSpaceType, queryDTO.getSpaceType());
        }
        
        if (queryDTO.getFeeType() != null) {
            queryWrapper.eq(FeeStandard::getFeeType, queryDTO.getFeeType());
        }
        
        if (queryDTO.getStatus() != null) {
            queryWrapper.eq(FeeStandard::getStatus, queryDTO.getStatus());
        }
        
        // 按创建时间降序排序
        queryWrapper.orderByDesc(FeeStandard::getCreatedAt);
        
        // 执行分页查询
        Page<FeeStandard> page = new Page<>(queryDTO.getPage(), queryDTO.getSize());
        IPage<FeeStandard> resultPage = this.page(page, queryWrapper);
        
        // 转换为 DTO
        IPage<FeeStandardDTO> dtoPage = resultPage.convert(this::convertToDTO);
        
        return dtoPage;
    }

    @Override
    public FeeStandardDTO getFeeStandardById(Integer id) {
        log.info("获取收费标准详情: {}", id);
        
        FeeStandard feeStandard = this.getById(id);
        if (feeStandard == null) {
            throw new BusinessException("收费标准不存在");
        }
        
        return convertToDTO(feeStandard);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public FeeStandardDTO createFeeStandard(FeeStandardDTO feeStandardDTO) {
        log.info("创建收费标准: {}", feeStandardDTO);
        
        // 检查名称是否重复
        checkNameDuplicate(feeStandardDTO.getName(), null);
        
        // 构建实体
        FeeStandard feeStandard = new FeeStandard();
        BeanUtils.copyProperties(feeStandardDTO, feeStandard);
        
        // 设置初始状态
        feeStandard.setStatus(feeStandardDTO.getStatus() != null ? feeStandardDTO.getStatus() : 1);
        
        // 保存
        if (!this.save(feeStandard)) {
            throw new BusinessException("创建收费标准失败");
        }
        
        return convertToDTO(feeStandard);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public FeeStandardDTO updateFeeStandard(Integer id, FeeStandardDTO feeStandardDTO) {
        log.info("更新收费标准: id={}, data={}", id, feeStandardDTO);
        
        // 检查是否存在
        FeeStandard existingFeeStandard = this.getById(id);
        if (existingFeeStandard == null) {
            throw new BusinessException("收费标准不存在");
        }
        
        // 检查名称是否重复
        checkNameDuplicate(feeStandardDTO.getName(), id);
        
        // 更新属性
        BeanUtils.copyProperties(feeStandardDTO, existingFeeStandard);
        existingFeeStandard.setId(id);
        
        // 保存
        if (!this.updateById(existingFeeStandard)) {
            throw new BusinessException("更新收费标准失败");
        }
        
        return convertToDTO(existingFeeStandard);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean deleteFeeStandard(Integer id) {
        log.info("删除收费标准: {}", id);
        
        // 检查是否存在
        FeeStandard existingFeeStandard = this.getById(id);
        if (existingFeeStandard == null) {
            throw new BusinessException("收费标准不存在");
        }
        
        // 删除
        return this.removeById(id);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public FeeStandardDTO changeFeeStandardStatus(Integer id, Integer status) {
        log.info("更改收费标准状态: id={}, status={}", id, status);
        
        // 检查是否存在
        FeeStandard existingFeeStandard = this.getById(id);
        if (existingFeeStandard == null) {
            throw new BusinessException("收费标准不存在");
        }
        
        // 更新状态
        existingFeeStandard.setStatus(status);
        
        // 保存
        if (!this.updateById(existingFeeStandard)) {
            throw new BusinessException("更新收费标准状态失败");
        }
        
        return convertToDTO(existingFeeStandard);
    }
    
    /**
     * 检查名称是否重复
     *
     * @param name 名称
     * @param id   排除的ID
     */
    private void checkNameDuplicate(String name, Integer id) {
        LambdaQueryWrapper<FeeStandard> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(FeeStandard::getName, name);
        
        if (id != null) {
            queryWrapper.ne(FeeStandard::getId, id);
        }
        
        if (this.count(queryWrapper) > 0) {
            throw new BusinessException("收费标准名称已存在");
        }
    }
    
    /**
     * 将实体转换为DTO
     *
     * @param feeStandard 收费标准实体
     * @return 收费标准DTO
     */
    private FeeStandardDTO convertToDTO(FeeStandard feeStandard) {
        FeeStandardDTO dto = new FeeStandardDTO();
        BeanUtils.copyProperties(feeStandard, dto);
        return dto;
    }
} 